home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / WINDOWS / BOUNCER.ARJ / BOUNCER.C < prev    next >
C/C++ Source or Header  |  1992-07-17  |  15KB  |  511 lines

  1. /*  BOUNCER.C - ScreenSaverProc(), RegisterDialogClasses(),
  2.  *   ScreenSaverConfigureDialog() and other support code for
  3.  *   BOUNCER.
  4.  *
  5.  *   BOUNCER is a sample screen saver application. It bounces a
  6.  *   bitmap across the display and produces a sound when the
  7.  *   bitmap image is at the bottom of the screen.
  8.  *
  9.  *    (C) Copyright Microsoft Corp. 1991.  All rights reserved.
  10.  *
  11.  *    You have a royalty-free right to use, modify, reproduce and
  12.  *    distribute the Sample Files (and/or any modified version) in
  13.  *    any way you find useful, provided that you agree that
  14.  *    Microsoft has no warranty obligations or liability for any
  15.  *    Sample Application Files which are modified.
  16.  */
  17. // COPYRIGHT:
  18. //
  19. //   (C) Copyright Microsoft Corp. 1992.  All rights reserved.
  20. //
  21. //   You have a royalty-free right to use, modify, reproduce and
  22. //   distribute the Sample Files (and/or any modified version) in
  23. //   any way you find useful, provided that you agree that
  24. //   Microsoft has no warranty obligations or liability for any
  25. //   Sample Application Files which are modified.
  26. #include <windows.h>
  27. #include <mmsystem.h>
  28. #include "bouncer.h"
  29.  
  30.  
  31. /* Global used by SCRNSAVE.LIB. Required for all screen savers.
  32.  */
  33.  
  34. char szAppName[40];
  35.  
  36.  
  37. /* Globals specific to BOUNCER.
  38.  */
  39.  
  40. char szDIBName[] = "BounceDIB";
  41.  
  42. char szSpeedName[] = "Speed";
  43.  
  44. char szXPosName[] = "xPosition";
  45.  
  46. char szYPosName[] = "yPosition";
  47.  
  48. char szXVelocityName[] = "xVelocity";
  49.  
  50. char szGravityName[] = "Gravity";
  51.  
  52. char szSoundName[] = "Sound";
  53.  
  54. char szDIBNumName[] = "DIBNum";
  55.  
  56. char szPauseName[] = "Pause at bottom";
  57.  
  58. char szName[] = "Bounce a bitmap";
  59.  
  60. /* Externals defined in SCRNSAVE.LIB. Required for all screen savers.
  61.  */
  62.  
  63. HINSTANCE _cdecl hMainInstance;
  64.  
  65. HWND _cdecl hMainWindow;
  66.  
  67. char _cdecl szName[TITLEBARNAMELEN];
  68.  
  69. char _cdecl szIsPassword[22];
  70.  
  71. char _cdecl szIniFile[MAXFILELEN];
  72.  
  73. char _cdecl szScreenSaver[22];
  74.  
  75. char _cdecl szPassword[16];
  76.  
  77. char _cdecl szDifferentPW[BUFFLEN];
  78.  
  79. char _cdecl szChangePW[30];
  80.  
  81. char _cdecl szBadOldPW[BUFFLEN];
  82.  
  83. char _cdecl szHelpFile[MAXFILELEN];
  84.  
  85. char _cdecl szNoHelpMemory[BUFFLEN];
  86.  
  87. UINT _cdecl MyHelpMessage;
  88.  
  89. HOOKPROC _cdecl fpMessageFilter;
  90.  
  91. HBITMAP hbmImage;                   // image handle
  92.  
  93. WORD wElapse;                       // speed parameter
  94.  
  95. WORD wTimer;                        // timer id
  96.  
  97. BOOL bBottom;                       // TRUE if frog is at bottom of screen
  98.  
  99. int xPos;                           // current x position
  100.  
  101. int yPos;                           // current y position
  102.  
  103. int xPosInit;                       // initial x position
  104.  
  105. int yPosInit;                       // initial y position
  106.  
  107. int xVelocInit;                     // x initial velocity
  108.  
  109. int nGravity;                       // acceleration factor
  110.  
  111. BOOL bSound;                        // sound on/off flag
  112.  
  113. BOOL bPause;                        // stick at bottom of screen?
  114.  
  115. BOOL bPassword;                     // password protected?
  116.  
  117. HANDLE hresWave;                    // handle to sound resource
  118.  
  119. LPSTR lpWave;                       // pointer to wave resource
  120.  
  121.  
  122. /* ScreenSaverProc - Main entry point for screen saver messages.
  123.  *  This function is required for all screen savers.
  124.  *
  125.  * Params:  Standard window message handler parameters.
  126.  *
  127.  * Return:  The return value depends on the message.
  128.  *
  129.  *  Note that all messages go to the DefScreenSaverProc(), except
  130.  *  for ones we process.
  131.  */
  132.  
  133.  
  134. LONG FAR PASCAL ScreenSaverProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM
  135.                                  lParam)
  136. {
  137.    RECT rc;
  138.    static WORD wBottomCount;
  139.  
  140.    switch (msg)
  141.       {
  142.    case WM_CREATE:                             // BOUNCER-specific
  143.    {
  144.       HANDLE hResInfo;
  145.  
  146.       /* Load the strings from the STRINGTABLE
  147.        */
  148.  
  149.       GetIniEntries();
  150.  
  151.       /* Load the initial bounce settings.
  152.        */
  153.       GetIniSettings();
  154.  
  155.       /* Load the DIB image we want to use.
  156.        */
  157.       hbmImage = LoadBitmap(hMainInstance, szDIBName);
  158.  
  159.       /* Load and lock the sound resource
  160.        */
  161.       if (hResInfo = FindResource(hMainInstance, "Sound", "WAVE"))
  162.       {
  163.          if (hresWave = LoadResource(hMainInstance, hResInfo))
  164.          {
  165.             lpWave = LockResource(hresWave);
  166.          }
  167.       }
  168.  
  169.       /* Create a timer to move the image
  170.        */
  171.       wTimer = SetTimer(hWnd, ID_TIMER, wElapse, NULL);
  172.       xPos = xPosInit;
  173.       yPos = yPosInit;
  174.       break;
  175.    }
  176.  
  177.    case WM_TIMER:                              // BOUNCER-specific
  178.       if (bPause && bBottom)
  179.       {
  180.          if (++wBottomCount == 10)
  181.          {
  182.             wBottomCount = 0;
  183.             bBottom = FALSE;
  184.          }
  185.          break;
  186.       }
  187.  
  188.       /* Move the image around a bit
  189.        */
  190.       MoveImage(hWnd);
  191.       break;
  192.  
  193.    case WM_DESTROY:                            // BOUNCER-specific
  194.  
  195.       /* Destroy any objects we created
  196.        */
  197.       if (hbmImage)
  198.          DeleteObject(hbmImage);
  199.       if (wTimer)
  200.          KillTimer(hWnd, ID_TIMER);
  201.       sndPlaySound(NULL, 0);
  202. /*s-*/ if( lpWave )   UnlockResource(hresWave); /*s+*/
  203.       if (hresWave)
  204.          FreeResource(hresWave);
  205.       break;
  206.  
  207.    case WM_ERASEBKGND:
  208.       GetClientRect(hWnd, &rc);
  209.       FillRect((HDC)wParam, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
  210.       return 0L;
  211.  
  212.    default:
  213.       break;
  214.       }
  215.    return DefScreenSaverProc(hWnd, msg, wParam, lParam);
  216. }
  217.  
  218. /* RegisterDialogClasses -- Entry point for registering window
  219.  * classes required by configuration dialog box.
  220.  *
  221.  * Params:  hWnd -- Handle to window
  222.  *
  223.  * Return:  None
  224.  */
  225.  
  226.  
  227. BOOL RegisterDialogClasses (HINSTANCE hInst)
  228. {
  229.    return TRUE;
  230. }
  231.  
  232.  
  233. /* ScreenSaverConfigureDialog -- Dialog box function for configuration
  234.  * dialog.
  235.  *
  236.  * Params:  hWnd -- Handle to window
  237.  *
  238.  * Return:  None
  239.  */
  240.  
  241.  
  242. BOOL FAR PASCAL ScreenSaverConfigureDialog (HWND hDlg, UINT msg, WPARAM wParam,
  243.                                             LPARAM lParam)
  244. {
  245.    static HWND hIDOK;
  246.    static HWND hSetPassword;
  247.  
  248.    switch (msg)
  249.       {
  250.    case WM_INITDIALOG:                         // BOUNCER-specific
  251.       GetIniEntries();
  252.       GetIniSettings();
  253.       SetDlgItemInt(hDlg, ID_SPEED, wElapse, FALSE);
  254.       SetDlgItemInt(hDlg, ID_XPOS, xPosInit, TRUE);
  255.       SetDlgItemInt(hDlg, ID_YPOS, yPosInit, TRUE);
  256.       SetDlgItemInt(hDlg, ID_VELOCITY, xVelocInit, TRUE);
  257.       SetDlgItemInt(hDlg, ID_GRAVITY, nGravity, TRUE);
  258.       SendDlgItemMessage(hDlg, ID_SOUND, BM_SETCHECK, bSound, NULL);
  259.       SendDlgItemMessage(hDlg, ID_PAUSE, BM_SETCHECK, bPause, NULL);
  260.       SendDlgItemMessage(hDlg, ID_PASSWORDPROTECTED, BM_SETCHECK, bPassword,
  261.                          NULL);
  262.       hSetPassword = GetDlgItem(hDlg, ID_SETPASSWORD);
  263.       EnableWindow(hSetPassword, bPassword);
  264.       hIDOK = GetDlgItem(hDlg, IDOK);
  265.       return TRUE;
  266.  
  267.    case WM_COMMAND:                            // BOUNCER-specific
  268.       switch (wParam)
  269.          {
  270.       case IDOK:
  271.          wElapse = GetDlgItemInt(hDlg, ID_SPEED, NULL, FALSE);
  272.          xPosInit = GetDlgItemInt(hDlg, ID_XPOS, NULL, TRUE);
  273.          yPosInit = GetDlgItemInt(hDlg, ID_YPOS, NULL, TRUE);
  274.          xVelocInit = GetDlgItemInt(hDlg, ID_VELOCITY, NULL, TRUE);
  275.          nGravity = GetDlgItemInt(hDlg, ID_GRAVITY, NULL, TRUE);
  276.          bSound = IsDlgButtonChecked(hDlg, ID_SOUND);
  277.          bPause = IsDlgButtonChecked(hDlg, ID_PAUSE);
  278.          bPassword = IsDlgButtonChecked(hDlg, ID_PASSWORDPROTECTED);
  279.          WriteProfileInt(szAppName, szSpeedName, wElapse);
  280.          WriteProfileInt(szAppName, szXPosName, xPosInit);
  281.          WriteProfileInt(szAppName, szYPosName, yPosInit);
  282.          WriteProfileInt(szAppName, szXVelocityName, xVelocInit);
  283.          WriteProfileInt(szAppName, szGravityName, nGravity);
  284.          WriteProfileInt(szAppName, szSoundName, bSound);
  285.          WriteProfileInt(szAppName, szPauseName, bPause);
  286.          WriteProfileInt(szAppName, szIsPassword, bPassword);
  287.          EndDialog(hDlg, TRUE);
  288.          return TRUE;
  289.  
  290.       case IDCANCEL:
  291.          EndDialog(hDlg, FALSE);
  292.          return TRUE;
  293.  
  294.       case ID_SETPASSWORD:
  295.       {
  296.          FARPROC fpDialog;
  297.  
  298.          if ((fpDialog = MakeProcInstance(DlgChangePassword, hMainInstance)) ==
  299.              NULL)
  300.             return FALSE;
  301.          DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_CHANGEPASSWORD), hDlg,
  302.                    fpDialog);
  303.          FreeProcInstance(fpDialog);
  304.          SendMessage(hDlg, WM_NEXTDLGCTL, hIDOK, 1l);
  305.          break;
  306.       }
  307.  
  308.       case ID_PASSWORDPROTECTED:
  309.          bPassword ^= 1;
  310.          CheckDlgButton(hDlg, wParam, bPassword);
  311.          EnableWindow(hSetPassword, bPassword);
  312.          break;
  313.  
  314.       case ID_HELP:
  315.          DoHelp:
  316.       #if 0
  317.                           bHelpActive=WinHelp(hDlg, szHelpFile, HELP_CONTEXT, IDH_DLG_BOUNCER);
  318.                           if (!bHelpActive)
  319.                               MessageBox(hDlg, szNoHelpMemory, szName, MB_OK);
  320.       #else
  321.          MessageBox(hDlg, "Insert your call to WinHelp() here.", szName, MB_OK)
  322.       ;
  323.       #endif
  324.          break;
  325.          }
  326.       break;
  327.  
  328.    default:
  329.       if (msg == MyHelpMessage)     // Context sensitive help msg.
  330.          goto DoHelp;
  331.       }
  332.    return FALSE;
  333. }
  334.  
  335.  
  336. /* THE REST OF THIS FILE IS SPECIFIC TO BOUNCER.
  337.  *
  338.  * Replace it with your own screen saver code.
  339.  */
  340.  
  341.  
  342. /* GetIniSettings -- Get initial bounce settings from WIN.INI
  343.  *
  344.  * Params:  hWnd -- Handle to window
  345.  *
  346.  * Return:  None
  347.  */
  348.  
  349.  
  350. static void GetIniSettings ()
  351. {
  352.    wElapse = GetPrivateProfileInt(szAppName, szSpeedName, DEF_SPEED, szIniFile)
  353.    ;
  354.    xPosInit = GetPrivateProfileInt(szAppName, szXPosName, DEF_INIT_XPOS,
  355.                                    szIniFile);
  356.    yPosInit = GetPrivateProfileInt(szAppName, szYPosName, DEF_INIT_YPOS,
  357.                                    szIniFile);
  358.    xVelocInit = GetPrivateProfileInt(szAppName, szXVelocityName, DEF_INIT_VELOC
  359.                                      , szIniFile);
  360.    nGravity = GetPrivateProfileInt(szAppName, szGravityName, DEF_INIT_GRAVITY,
  361.                                    szIniFile);
  362.    bSound = GetPrivateProfileInt(szAppName, szSoundName, DEF_SOUND, szIniFile);
  363.    bPause = GetPrivateProfileInt(szAppName, szPauseName, DEF_PAUSE, szIniFile);
  364.    bPassword = GetPrivateProfileInt(szAppName, szIsPassword, FALSE, szIniFile);
  365. }
  366.  
  367. /* MoveImage -- Move image around the screen
  368.  *
  369.  * Params:  hWnd -- Handle to window
  370.  *
  371.  * Return:  None
  372.  */
  373.  
  374.  
  375. static void MoveImage (HWND hWnd)
  376. {
  377. //    static int xPos = 10000;            // Current x value (force a reset)
  378. //    static int yPos = 0;                // Current y value
  379.    static int yVeloc = 0;              // Current y velocity
  380.    int xPosOld, yPosOld;
  381.    HDC hDC;                            // Handle to our window DC
  382.    HDC hMemDC;                         // Handle to a memory DC
  383.    BITMAP bm;                          // Bitmap info
  384.    HBITMAP hbmOld;
  385.    RECT rcWnd, rcFill;
  386.  
  387.    /* Get window size
  388.     */
  389.  
  390.    GetClientRect(hWnd, &rcWnd);
  391.  
  392.    /* Get bitmap size
  393.     */
  394.    GetObject(hbmImage, sizeof(bm), (LPSTR)&bm);
  395.  
  396.    /* Update x- and y-position values
  397.     */
  398.    xPosOld = xPos;
  399.    yPosOld = yPos;
  400.    yVeloc += nGravity;
  401.    xPos += xVelocInit;
  402.    yPos += yVeloc;
  403.  
  404.    /* If we're at the bottom, BOUNCE!
  405.     */
  406.    if ((yPos + bm.bmHeight > rcWnd.bottom) && (yVeloc > 0))
  407.    {
  408.       yVeloc = -yVeloc;                   // Reverse directions
  409.       if (bSound && lpWave)               // Boing!!! 
  410.       {
  411.          // do the multimedia bit
  412.          sndPlaySound(lpWave, SND_ASYNC | SND_MEMORY | SND_NODEFAULT);
  413.       }
  414.       bBottom = TRUE;
  415.    }
  416.  
  417.    /* If we're off the right of the screen, or off the bottom of the
  418.     * screen, start over at beginning position and zero y-velocity.
  419.     */
  420.    if ((xPos > rcWnd.right) || (yPos > rcWnd.bottom))
  421.    {
  422.       yVeloc = 0;
  423.       xPos = xPosInit;
  424.       yPos = yPosInit;
  425.    }
  426.  
  427.    /* Get a DC to our window.  Create a compatible memory
  428.     * DC and select our image bitmap into it so we can blit
  429.     * it to the main window DC
  430.     */
  431.    hDC = GetDC(hWnd);
  432.    hMemDC = CreateCompatibleDC(hDC);
  433.    hbmOld = SelectObject(hMemDC, hbmImage);
  434.    if (hbmOld)
  435.    {
  436.       /* Blit the image in the new position
  437.        */
  438.       BitBlt(hDC,                        // dest DC
  439.              xPos, yPos,                  // dest origin
  440.              bm.bmWidth, bm.bmHeight,     // dest extents
  441.              hMemDC,                     // src DC
  442.              0, 0,                        // src origin
  443.              SRCCOPY);                  // ROP code
  444.       SelectObject(hMemDC, hbmOld);
  445.  
  446.       /* Tidy up where the old image was by filling exposed bits with
  447.        * the background color
  448.        *
  449.        * This code assumes the image always moves to the right
  450.        */
  451.       rcFill.left = xPosOld;                        // Left bits
  452.       rcFill.top = yPosOld;
  453.       rcFill.right = xPos;
  454.       rcFill.bottom = rcFill.top + bm.bmHeight;
  455.       FillRect(hDC, &rcFill, GetStockObject(BLACK_BRUSH));
  456.       rcFill.right = rcFill.left + bm.bmWidth;        // Top or bottom bits
  457.       if (yPos > yPosOld)
  458.       {
  459.          rcFill.bottom = yPos;                       // Top bits
  460.       }
  461.       else
  462.       {
  463.          rcFill.top = yPos + bm.bmHeight;            // Bottom bits
  464.          rcFill.bottom = yPosOld + bm.bmHeight;
  465.       }
  466.       FillRect(hDC, &rcFill, GetStockObject(BLACK_BRUSH));
  467.    }
  468.    DeleteDC(hMemDC);
  469.    ReleaseDC(hWnd, hDC);
  470. }
  471.  
  472.  
  473.  
  474.  
  475. /* WriteProfileInt - Write an unsigned integer value to CONTROL.INI.
  476.  *
  477.  * Params:  name - szSection - [section] name in .INI file
  478.  *                 szKey     - key= in .INI file
  479.  *                 i         - value for key above
  480.  *
  481.  * Return:  None
  482.  */
  483.  
  484.  
  485. static void WriteProfileInt (LPSTR szSection, LPSTR szKey, int i)
  486. {
  487.    char achBuf[40];
  488.  
  489.    /* write out as unsigned because GetPrivateProfileInt() can't
  490.     * cope with signed values!
  491.     */
  492.  
  493.    wsprintf(achBuf, "%u", i);
  494.    WritePrivateProfileString(szSection, szKey, achBuf, szIniFile);
  495. }
  496.  
  497.  
  498. void GetIniEntries (void)
  499. {
  500.    //Load Common Strings from stringtable...
  501.    LoadString(hMainInstance, idsIsPassword, szIsPassword, 22);
  502.    LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN);
  503.    LoadString(hMainInstance, idsScreenSaver, szScreenSaver, 22);
  504.    LoadString(hMainInstance, idsPassword, szPassword, 16);
  505.    LoadString(hMainInstance, idsDifferentPW, szDifferentPW, BUFFLEN);
  506.    LoadString(hMainInstance, idsChangePW, szChangePW, 30);
  507.    LoadString(hMainInstance, idsBadOldPW, szBadOldPW, 255);
  508.    LoadString(hMainInstance, idsHelpFile, szHelpFile, MAXFILELEN);
  509.    LoadString(hMainInstance, idsNoHelpMemory, szNoHelpMemory, BUFFLEN);
  510. }
  511.